勾配ブースティング(Gradient Boosting)
Overview
勾配ブースティングは、複数の決定木を組み合わせてより強力なモデルを構築するアンサンブル手法の1つです。このモデルは回帰にもクラス分類にも利用できます。ランダムフォレスト(Random Forest)とは対照的に、勾配ブースティングでは、1つ前の決定木の誤りを次の決定木が修正するようにして、決定木を順番に作っていきます。 Theory
勾配ブースティングは、デフォルトでは乱数性がありません。その代わり、強力な事前枝刈りが用いられます。勾配ブースティングでは、深さ1から5くらいの非常に浅い決定木が用いられます。これによって、モデルの占めるメモリが小さくなり、予測も早くなります。ポイントは、このような簡単なモデル(弱学習機(weak learner))を多数組み合わせることにあります。それぞれの決定木はデータの一部に対してしか良い予測を行えないので、決定木を繰り返し追加していくことで、性能を向上させます。
Coding(Classification)
cancerデータセットでモデルを構築・学習・評価する
code: Python
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=0)
gbrt = GradientBoostingClassifier(random_state=0)
gbrt.fit(X_train, y_train)
print('Accuracy on training set: {:.3f}'.format(gbrt.score(X_train, y_train)))
print('Accuracy on test set: {:.3f}'.format(gbrt.score(X_test, y_test)))
--------------------------------------------------------------------------
Accuracy on training set: 1.000
Accuracy on test set: 0.958
--------------------------------------------------------------------------
これはおそらく過剰適合しているので、深さの最大値を制限してより強力な事前枝刈りを行うか、学習率を下げればよいです。
学習率とは、それまでの決定木の過ちをどれくらい強く補正するかを制御するパラメータで、学習率を大きくすると、個々の決定木が強く補正を行おうとし、モデルは複雑になります。
cancerデータセットで事前枝刈りしてモデルを構築・学習・評価する
code: Python
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=0)
gbrt = GradientBoostingClassifier(random_state=0, max_depth=1)
gbrt.fit(X_train, y_train)
print('Accuracy on training set: {:.3f}'.format(gbrt.score(X_train, y_train)))
print('Accuracy on test set: {:.3f}'.format(gbrt.score(X_test, y_test)))
--------------------------------------------------------------------------
Accuracy on training set: 0.991
Accuracy on test set: 0.972
--------------------------------------------------------------------------
cancerデータセットで学習率を調整してモデルを構築・学習・評価する
code: Python
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=0)
gbrt = GradientBoostingClassifier(random_state=0, learning_rate=0.01)
gbrt.fit(X_train, y_train)
print('Accuracy on training set: {:.3f}'.format(gbrt.score(X_train, y_train)))
print('Accuracy on test set: {:.3f}'.format(gbrt.score(X_test, y_test)))
--------------------------------------------------------------------------
Accuracy on training set: 1.000
Accuracy on test set: 0.958
--------------------------------------------------------------------------
Advanced
勾配ブースティングの特徴量の重要性
他の決定木ベースのモデルと同様に、特徴量の重要度を可視化してモデルの詳細を見ることができます。
code: Python
gbrt = GradientBoostingClassifier(random_state=0, max_depth=1)
gbrt.fit(X_train, y_train)
def plot_feature_importances_cancer(model):
n_features = cancer.data.shape1 plt.barh(range(n_features), model.feature_importances_, align='center')
plt.yticks(np.arange(n_features), cancer.feature_names)
plt.xlabel('Feature importance')
plt.ylabel('Feature')
plot_feature_importances_cancer(gbrt)
https://gyazo.com/27368a95cd878670cbe10db99a141166
勾配ブースティングでは、いくつかの特徴量が完全に無視されていることがわかります。勾配ブースティングとランダムフォレストは、同じようなデータを得意とするので、一般には頑健性のあるランダムフォレストを先に試したほうがよいです。予測時間が非常に重要な場合や、機械学習モデルから最後の1%まえ性能を絞り出したい場合には勾配ブースティングを試してみたほうがよいです。
Summary
Merit
パラメータさえ正しく設定されていればランダムフォレストより性能が良い
特徴量ごとにスケールが大きく異なるような場合でも問題なく機能する
機械学習コンペティションでしばしば優勝している
産業界でも広く使われている
Demerit
ランダムフォレストに比べるとパラメータ設定の影響を受けやすい
学習にかかる時間が長い
非常に高次元で疎なデータに対してはうまく機能しない傾向がある
Parameters
learning_rate (学習率)
個々の決定木が、それまでの決定木の過ちをどれくらい強く補正するかを制御する
学習率を大きくすると、個々の決定木が強く補正を行おうとし、モデルは複雑になる
n_estimators
アンサンブル中の決定木の数
これを増やすと訓練セットに対する過ちを補正する機会が増えるので、モデルは複雑になる
大きくしすぎると過剰学習を招く
max_depth
個々の決定木の複雑さを減らす
デフォルトでは非常に小さな値(深さが5以上になることはあまりない)